# !/usr/bin/env python
# -*- coding:utf-8 -*-

from bottle import Bottle, request, response

from conn.MyPagerFactory import MyPager
from conn.MySqlFactory import MySqlConfig
from schedu.ScheduleService import ScheduleService
from schedu.bean.Schedule import Schedule

scheduAdm = Bottle()
_sql = MySqlConfig('172.17.0.9', 'tuut', 'tuut', 'qrtz', 33069)
schedu_conn = _sql.conn()

@scheduAdm.hook('before_request')
def validate():
    REQUEST_METHOD = request.environ.get('REQUEST_METHOD')
    HTTP_ACCESS_CONTROL_REQUEST_METHOD = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_METHOD')
    if REQUEST_METHOD == 'OPTIONS' and HTTP_ACCESS_CONTROL_REQUEST_METHOD:
        request.environ['REQUEST_METHOD'] = HTTP_ACCESS_CONTROL_REQUEST_METHOD


@scheduAdm.hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'  # 允许所有域名的请求
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, DELETE, PUT, HEAD, OPTIONS'
    response.headers['Access-Control-Allow-Headers'] = 'origin,content-type,accept,authorization,x-requested-with'
    response.headers["Access-Control-Allow-Credentials"] = "true"
    response.headers['Access-Control-Max-Age'] = 86400
    response.status = 200

# 定时任务业务
class ScheduleAdminRoute:
    exec_times = []
    ERROR_CODE = {
        "99": "处理参数错误",
        "100": "任务名称重复，数据添加失败",
        "101": "任务名称错误，请重新输入",
        "102": "任务名称不存在，数据更新失败",
        "103": "任务名称不存在，数据删除失败",
        "104": "任务数据后台停止失败，请检查服务端日志",
        "105": "任务数据后台恢复失败，请检查服务端日志",
        "106": "任务数据后台激活失败，请检查服务端日志",
        "109": "任务名称不存在，数据处理失败",
    }

    @staticmethod
    @scheduAdm.get('/fetch')
    def fetchtr():
        params = {"key": str(request.params.key).replace(" ", ""),
                  "pageSize": int(request.params.pageSize),
                  "pageNum": int(request.params.pageNum)}
        res = ScheduleService.get_schedus(params)
        _pages = MyPager.make_pager(id="schedule", res=res['data'], page_size=int(params['pageSize']),
                                    data_total=res['total'], single_pager=False)
        return {'code': 200, 'data': {'list': _pages["lists"],
                                      'total': _pages["total"],
                                      'currentPage': params['pageNum'],
                                      'pageSize': params['pageSize'],
                                      'pages': _pages["pages"]}, 'message': ''}

    @staticmethod
    @scheduAdm.get('/info')
    def infoApi():
        res = ScheduleService.info(int(request.params.id))
        return {'code': 200, 'data': res["data"], 'message': ''}

    @staticmethod
    @scheduAdm.get('/one')
    def one():
        job_name = request.params.jobName
        _chooseData = ScheduleService.get_schedus(job_name)
        return {'code': 200, 'data': _chooseData['data'][0], 'message': ''}

    @staticmethod
    @scheduAdm.post('/handleAdd')
    def handle_add():
        import datetime
        job_name = request.forms.jobName
        job_group_name = request.forms.jobGroupName
        job_class = request.forms.jobClass
        trigger_name = request.forms.triggerName
        trigger_group_name = request.forms.triggerGroupName
        cron_expression = request.forms.cronExpression
        call_back = request.forms.callBack
        str(call_back).replace("\"","")
        if len(job_name) == 0:
            return {'code': 500, 'data': None, 'message': ScheduleAdminRoute.ERROR_CODE['99']}
        trigger_time = datetime.datetime.now().strftime("%Y%m%d")
        trigger_name = trigger_name +"_"+ trigger_time
        _sql_str = "SELECT count(1) FROM QRTZ_JOB_DETAILS WHERE job_name = '%s'" % job_name
        data_list = MySqlConfig.sql_execute(_sql, _sql_str)
        if data_list[0][0] == 0:
            schedule = Schedule(job_name, job_group_name, job_class,
                                trigger_name, trigger_group_name, cron_expression, call_back)
            res = ScheduleService.client_push_schedu(schedule)
            if res['code'] == 200:
                res = ScheduleService.add_schedu(schedule)
                if res['code'] == 200:
                    return {'code': 200, 'data': {}, 'message': ''}
            else:
                return {'code': 500, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['100']}
        else:
            return {'code': 500, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['100']}

    @staticmethod
    @scheduAdm.put('/handleUpdate')
    def handle_update():
        if request.json is not None:
            job_name = request.json['jobName']
            job_group_name = request.json['jobGroupName']
            job_class = request.json['jobClass']
            trigger_name = request.json['triggerName']
            trigger_group_name = request.json['triggerGroupName']
            cron_expression = request.json['cronExpression']
            call_back = request.json['callBack']
        else:
            return {'code': 500, 'data': None, 'message': ScheduleAdminRoute.ERROR_CODE['99']}

        _sql_str = "SELECT count(1) FROM QRTZ_JOB_DETAILS WHERE job_name = '%s'" % job_name
        data_list = MySqlConfig.sql_execute(_sql, _sql_str)
        if data_list[0][0] > 0:
            schedule = Schedule(job_name, job_group_name, job_class,
                                trigger_name, trigger_group_name, cron_expression, call_back)
            res = ScheduleService.client_reset_schedu(schedule)
            if res['code'] == 200:
                res = ScheduleService.update_schedu(int(request.json['id']), schedule)
                if res['code'] == 200:
                    return {'code': 200, 'data': {}, 'message': ''}
            else:
                return {'code': 502, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['102']}
        else:
            return {'code': 509, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['109']}

    @staticmethod
    @scheduAdm.delete('/handleDelete')
    def handle_delete():
        id = request.params.id
        times = request.params.times
        # 这里有一个诡异的二次触发，不知道是不是bottle的bug，这里会有一次重复。加入一个时间戳，判定是否执行过。
        if times not in ScheduleAdminRoute.exec_times:
            ScheduleAdminRoute.exec_times.append(times)
        else:
            return {'code': 200, 'data': {}, 'message': ''}
        if id == 0 or len(str(id)) == 0:
            return {'code': 500, 'data': None, 'message': ScheduleAdminRoute.ERROR_CODE["99"]}

        schedu_data = ScheduleService.info(id)['data']
        if len(schedu_data) == 0:
            return {'code': 509, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['109']}
        _sql_str = "SELECT count(1) FROM QRTZ_JOB_DETAILS WHERE job_name = '%s'" % schedu_data['jobName']
        data_list = MySqlConfig.sql_execute(_sql, _sql_str)
        if data_list[0][0] > 0:
            schedule = Schedule(schedu_data['jobName'], schedu_data['jobGroupName'], "", "", "", "", "")
            res = ScheduleService.client_delete_schedu(schedule)
            if res['code'] == 200:
                ScheduleService.del_schedu(schedule)
                return {'code': 200, 'data': {}, 'message': ''}
            else:
                return {'code': 503, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['103']}
        else:
            return {'code': 509, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['109']}

    # 暂停任务 #
    @staticmethod
    @scheduAdm.put('/handlePause')
    def handle_pause():
        if request.json is not None:
            job_name = request.json['jobName']
            job_group_name = request.json['jobGroupName']
        else:
            return {'code': 500, 'data': None, 'message': ScheduleAdminRoute.ERROR_CODE['99']}

        _sql_str = "SELECT count(1) FROM QRTZ_JOB_DETAILS WHERE job_name = '%s'" % job_name
        data_list = MySqlConfig.sql_execute(_sql, _sql_str)
        if data_list[0][0] > 0:
            schedule = Schedule(job_name, job_group_name, "", "", "", "", "")
            res = ScheduleService.client_pause_schedu(schedule)
            if res['code'] == 200:
                return {'code': 200, 'data': {}, 'message': ''}
            else:
                return {'code': 504, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['104']}
        else:
            return {'code': 509, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['109']}

    # 恢复任务 #
    @staticmethod
    @scheduAdm.put('/handleResume')
    def handle_resume():
        if request.json is not None:
            job_name = request.json['jobName']
            job_group_name = request.json['jobGroupName']
        else:
            return {'code': 500, 'data': None, 'message': ScheduleAdminRoute.ERROR_CODE['99']}

        _sql_str = "SELECT count(1) FROM QRTZ_JOB_DETAILS WHERE job_name = '%s'" % job_name
        data_list = MySqlConfig.sql_execute(_sql, _sql_str)
        if data_list[0][0] > 0:
            schedule = Schedule(job_name, job_group_name, "", "", "", "", "")
            res = ScheduleService.client_resume_schedu(schedule)
            if res['code'] == 200:
                return {'code': 200, 'data': {}, 'message': ''}
            else:
                return {'code': 505, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['105']}
        else:
            return {'code': 509, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['109']}

    # 更新激活时间 #
    @staticmethod
    @scheduAdm.put('/handleRef')
    def handle_ref():
        if request.json is not None:
            job_name = request.json['jobName']
            job_group_name = request.json['jobGroupName']
        else:
            return {'code': 500, 'data': None, 'message': ScheduleAdminRoute.ERROR_CODE['99']}

        _sql_str = "SELECT count(1) FROM QRTZ_JOB_DETAILS WHERE job_name = '%s'" % job_name
        data_list = MySqlConfig.sql_execute(_sql, _sql_str)
        if data_list[0][0] > 0:
            schedule = Schedule(job_name, job_group_name, "", "", "", "", "")
            res = ScheduleService.client_ref_schedu(schedule)
            if res['code'] == 200:
                return {'code': 200, 'data': {}, 'message': ''}
            else:
                return {'code': 506, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['106']}
        else:
            return {'code': 509, 'data': {}, 'message': ScheduleAdminRoute.ERROR_CODE['109']}
